package cn.deschen.app.controller;

import cn.deschen.biz.dto.search.AdSearchFetchDTO;
import cn.deschen.biz.dto.search.AdSearchVO;
import cn.deschen.biz.dto.search.feature.FeatureRelation;
import cn.deschen.biz.dto.search.media.AdSlot;
import cn.deschen.biz.dto.search.scope.ParamScope;
import cn.deschen.common.api.CmRes;
import cn.deschen.search.index.adCreative.AdCreativeIndex;
import cn.deschen.search.index.adCreative.AdCreativeObject;
import cn.deschen.search.index.adUnit.AdUnitIndex;
import cn.deschen.search.index.adUnit.AdUnitObject;
import cn.deschen.search.index.adUnitEle.adUnitCreative.AdUnitCreativeIndex;
import cn.deschen.search.index.adUnitEle.adUnitKeyword.AdUnitKeywordIndex;
import cn.deschen.search.index.adUnitEle.adUnitRegion.AdUnitRegionIndex;
import cn.deschen.search.index.adUnitEle.adUnitTag.AdUnitTagIndex;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import ma.glasnost.orika.MapperFacade;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author hanbin_chen
 * @Description 广告搜索功能
 * @DateTime 2021/6/24
 * @Version V1.0.0
 */
@RestController
@Slf4j
@RequestMapping("/ad/search")
@Api(tags = "广告搜索功能")
public class AdSearchController {

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private AdUnitIndex unitIndex;

    @Autowired
    private AdUnitTagIndex unitTagIndex;

    @Autowired
    private AdUnitKeywordIndex unitKeywordIndex;

    @Autowired
    private AdUnitRegionIndex unitRegionIndex;

    @Autowired
    private AdUnitCreativeIndex unitCreativeIndex;

    @Autowired
    private AdCreativeIndex creativeIndex;


    /**
     * 根据条件获取广告列表
     *
     * @param fetchDTO
     * @return
     */
    @ApiOperation("获取广告")
    @PostMapping("/fetchAds")
    public CmRes<AdSearchVO> fetchAds(@RequestBody AdSearchFetchDTO fetchDTO) {

        List<AdSlot> adSlotList = fetchDTO.getRequestInfo().getAdSlots();
        Map<String, List<AdSearchVO.CreativeVO>> creativeVOMap = new HashMap<>();
        for (AdSlot adSlot : adSlotList) {
            Set<Long> unitIdSet = matchUnitPositionType(adSlot.getPositionType());
            if (CollectionUtils.isEmpty(unitIdSet)) {
                continue;
            }

            unitIdSet = matchUnitFeature(fetchDTO, unitIdSet);
            List<AdSearchVO.CreativeVO> creativeVOList = Collections.emptyList();
            if (CollectionUtils.isEmpty(unitIdSet)) {
                continue;
            }

            Set<Long> creativeIdList = unitCreativeIndex.matchUnit(unitIdSet);
            List<AdCreativeObject> creativeObjectList = creativeIndex.matchCreative(creativeIdList);
            if (CollectionUtils.isEmpty(creativeObjectList)) {
                continue;
            }

            creativeObjectList = creativeObjectList.stream()
                    .filter(creativeObject -> creativeObject.matchCreativeAdSlot(adSlot))
                    .collect(Collectors.toList());

            creativeVOList = mapperFacade.mapAsList(creativeObjectList, AdSearchVO.CreativeVO.class);
            creativeVOMap.put(adSlot.getPositionType(), creativeVOList);

        }
        AdSearchVO searchVO = new AdSearchVO();
        searchVO.setCreativeList(creativeVOMap);
        return CmRes.success(searchVO);
    }

    private Set<Long> matchUnitFeature(AdSearchFetchDTO fetchDTO, Set<Long> unitIdSet) {
        // 推广单元匹配条件-兴趣标签
        List<Long> tagKeyList = fetchDTO.getFeatureInfo().getTagFeature().getTagIds();
        Set<Long> matchTagUnitIdSet = unitTagIndex.matchTag(unitIdSet, tagKeyList);

        // 推广单元匹配条件-关键字
        List<Long> keywordKeyList = fetchDTO.getFeatureInfo().getKeywordFeature().getKeywordIds();
        Set<Long> matchKeywordUnitIdSet = unitKeywordIndex.matchKeyword(unitIdSet, keywordKeyList);

        // 推广单元匹配条件-地理位置
        List<String> locationKeyList = fetchDTO.getFeatureInfo().getRegionFeature().getLocations().stream()
                .map(value -> value.getProvince() + ":" + value.getCity()).collect(Collectors.toList());
        Set<Long> matchRegionUnitIdSet = unitRegionIndex.matchRegion(unitIdSet, locationKeyList);

        // 根据匹配条件关系筛选推广单元
        if (fetchDTO.getFeatureInfo().getRelation().equals(FeatureRelation.AND)) {
            matchTagUnitIdSet.retainAll(matchKeywordUnitIdSet);
            matchTagUnitIdSet.retainAll(matchRegionUnitIdSet);
        } else {
            matchTagUnitIdSet.addAll(matchKeywordUnitIdSet);
            matchTagUnitIdSet.addAll(matchRegionUnitIdSet);
        }
        return matchTagUnitIdSet;
    }

    private Set<Long> matchUnitPositionType(String positionType) {
        // 通过广告位筛选推广单元
        Set<AdUnitObject> unitObjectSet = unitIndex.match(positionType);
        Set<Long> unitIdSet = unitObjectSet.stream().map(AdUnitObject::getId).collect(Collectors.toSet());
        return unitIdSet;
    }

}
